home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / djgpp / src / gas-211 / gas / config / obj-aout.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-30  |  15.8 KB  |  633 lines

  1. /* a.out object file format
  2.    Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as
  8. published by the Free Software Foundation; either version 2,
  9. or (at your option) any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful, but
  12. WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  14. the GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public
  17. License along with GAS; see the file COPYING.  If not, write
  18. to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  19.  
  20. #include "as.h"
  21. #include "aout/stab_gnu.h"
  22. #include "obstack.h"
  23.  
  24. #ifndef BFD_ASSEMBLER
  25. /* in: segT   out: N_TYPE bits */
  26. const short seg_N_TYPE[] =
  27. {
  28.   N_ABS,
  29.   N_TEXT,
  30.   N_DATA,
  31.   N_BSS,
  32.   N_UNDF,            /* unknown */
  33.   N_UNDF,            /* absent */
  34.   N_UNDF,            /* pass1 */
  35.   N_UNDF,            /* error */
  36.   N_UNDF,            /* bignum/flonum */
  37.   N_UNDF,            /* difference */
  38.   N_UNDF,            /* debug */
  39.   N_UNDF,            /* ntv */
  40.   N_UNDF,            /* ptv */
  41.   N_REGISTER,            /* register */
  42. };
  43.  
  44. const segT N_TYPE_seg[N_TYPE + 2] =
  45. {                /* N_TYPE == 0x1E = 32-2 */
  46.   SEG_UNKNOWN,            /* N_UNDF == 0 */
  47.   SEG_GOOF,
  48.   SEG_ABSOLUTE,            /* N_ABS == 2 */
  49.   SEG_GOOF,
  50.   SEG_TEXT,            /* N_TEXT == 4 */
  51.   SEG_GOOF,
  52.   SEG_DATA,            /* N_DATA == 6 */
  53.   SEG_GOOF,
  54.   SEG_BSS,            /* N_BSS == 8 */
  55.   SEG_GOOF,
  56.   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
  57.   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
  58.   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
  59.   SEG_REGISTER,            /* dummy N_REGISTER for regs = 30 */
  60.   SEG_GOOF,
  61. };
  62. #endif
  63.  
  64. static void obj_aout_stab PARAMS ((int what));
  65. static void obj_aout_line PARAMS ((void));
  66. static void obj_aout_desc PARAMS ((void));
  67.  
  68. const pseudo_typeS obj_pseudo_table[] =
  69. {
  70.   /* stabs debug info */
  71.   {"line", obj_aout_line, 0},    /* source code line number */
  72.   {"ln", obj_aout_line, 0},    /* coff line number that we use anyway */
  73.   {"desc", obj_aout_desc, 0},    /* desc */
  74.   {"stabd", obj_aout_stab, 'd'},/* stabs */
  75.   {"stabn", obj_aout_stab, 'n'},/* stabs */
  76.   {"stabs", obj_aout_stab, 's'},/* stabs */
  77.  
  78.   /* coff debug pseudos (ignored) */
  79.   {"def", s_ignore, 0},
  80.   {"dim", s_ignore, 0},
  81.   {"endef", s_ignore, 0},
  82.   {"ident", s_ignore, 0},
  83.   {"line", s_ignore, 0},
  84.   {"ln", s_ignore, 0},
  85.   {"scl", s_ignore, 0},
  86.   {"size", s_ignore, 0},
  87.   {"tag", s_ignore, 0},
  88.   {"type", s_ignore, 0},
  89.   {"val", s_ignore, 0},
  90.   {"version", s_ignore, 0},
  91.  
  92.   /* stabs-in-coff (?) debug pseudos (ignored) */
  93.   {"optim", s_ignore, 0},    /* For sun386i cc (?) */
  94.  
  95.   /* other stuff */
  96.   {"ABORT", s_abort, 0},
  97.  
  98.   {NULL}            /* end sentinel */
  99. };                /* obj_pseudo_table */
  100.  
  101.  
  102. #ifdef BFD_ASSEMBLER
  103.  
  104. void
  105. obj_aout_frob_symbol (sym, punt)
  106.      symbolS *sym;
  107.      int *punt;
  108. {
  109.   flagword flags;
  110.   asection *sec;
  111.   int desc, type, other;
  112.  
  113.   /* Is this part format-dependent?  */
  114.   if (sym->sy_forward)
  115.     {
  116.       S_SET_VALUE (sym,
  117.            S_GET_VALUE (sym)
  118.            + S_GET_VALUE (sym->sy_forward)
  119.            + sym->sy_forward->sy_frag->fr_address
  120.            );
  121.       sym->sy_forward = 0;
  122.     }
  123.  
  124.   flags = sym->bsym->flags;
  125.   desc = S_GET_DESC (sym);
  126.   type = S_GET_TYPE (sym);
  127.   other = S_GET_OTHER (sym);
  128.   sec = sym->bsym->section;
  129.  
  130.   /* Only frob simple symbols this way right now.  */
  131.   if (! (type & ~0x1f))
  132.     {
  133.       if (sec == &bfd_abs_section
  134.       || sec == &bfd_und_section)
  135.     return;
  136.       if (flags & BSF_EXPORT)
  137.     type |= 1;
  138.     }
  139.   else
  140.     {
  141.       sym->bsym->flags |= BSF_DEBUGGING;
  142.     }
  143.  
  144.   S_SET_TYPE (sym, type);
  145. }
  146.  
  147. #else
  148.  
  149. /* Relocation. */
  150.  
  151. /*
  152.  *        emit_relocations()
  153.  *
  154.  * Crawl along a fixS chain. Emit the segment's relocations.
  155.  */
  156. void
  157. obj_emit_relocations (where, fixP, segment_address_in_file)
  158.      char **where;
  159.      fixS *fixP;        /* Fixup chain for this segment. */
  160.      relax_addressT segment_address_in_file;
  161. {
  162.   for (; fixP; fixP = fixP->fx_next)
  163.     if (fixP->fx_addsy != NULL)
  164.       {
  165.     tc_aout_fix_to_chars (*where, fixP, segment_address_in_file);
  166.     *where += md_reloc_size;
  167.       }
  168. }
  169.  
  170. #ifndef obj_header_append
  171. /* Aout file generation & utilities */
  172. void
  173. obj_header_append (where, headers)
  174.      char **where;
  175.      object_headers *headers;
  176. {
  177.   tc_headers_hook (headers);
  178.  
  179. #ifdef CROSS_COMPILE
  180.   md_number_to_chars (*where, headers->header.a_info, sizeof (headers->header.a_info));
  181.   *where += sizeof (headers->header.a_info);
  182.   md_number_to_chars (*where, headers->header.a_text, sizeof (headers->header.a_text));
  183.   *where += sizeof (headers->header.a_text);
  184.   md_number_to_chars (*where, headers->header.a_data, sizeof (headers->header.a_data));
  185.   *where += sizeof (headers->header.a_data);
  186.   md_number_to_chars (*where, headers->header.a_bss, sizeof (headers->header.a_bss));
  187.   *where += sizeof (headers->header.a_bss);
  188.   md_number_to_chars (*where, headers->header.a_syms, sizeof (headers->header.a_syms));
  189.   *where += sizeof (headers->header.a_syms);
  190.   md_number_to_chars (*where, headers->header.a_entry, sizeof (headers->header.a_entry));
  191.   *where += sizeof (headers->header.a_entry);
  192.   md_number_to_chars (*where, headers->header.a_trsize, sizeof (headers->header.a_trsize));
  193.   *where += sizeof (headers->header.a_trsize);
  194.   md_number_to_chars (*where, headers->header.a_drsize, sizeof (headers->header.a_drsize));
  195.   *where += sizeof (headers->header.a_drsize);
  196.  
  197. #else /* CROSS_COMPILE */
  198.  
  199.   append (where, (char *) &headers->header, sizeof (headers->header));
  200. #endif /* CROSS_COMPILE */
  201.  
  202. }
  203. #endif
  204.  
  205. void
  206. obj_symbol_to_chars (where, symbolP)
  207.      char **where;
  208.      symbolS *symbolP;
  209. {
  210.   md_number_to_chars ((char *) &(S_GET_OFFSET (symbolP)), S_GET_OFFSET (symbolP), sizeof (S_GET_OFFSET (symbolP)));
  211.   md_number_to_chars ((char *) &(S_GET_DESC (symbolP)), S_GET_DESC (symbolP), sizeof (S_GET_DESC (symbolP)));
  212.   md_number_to_chars ((char *) &(S_GET_VALUE (symbolP)), S_GET_VALUE (symbolP), sizeof (S_GET_VALUE (symbolP)));
  213.  
  214.   append (where, (char *) &symbolP->sy_symbol, sizeof (obj_symbol_type));
  215. }
  216.  
  217. void
  218. obj_emit_symbols (where, symbol_rootP)
  219.      char **where;
  220.      symbolS *symbol_rootP;
  221. {
  222.   symbolS *symbolP;
  223.  
  224.   /* Emit all symbols left in the symbol chain.  */
  225.   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  226.     {
  227.       /* Used to save the offset of the name. It is used to point
  228.      to the string in memory but must be a file offset. */
  229.       register char *temp;
  230.  
  231.       temp = S_GET_NAME (symbolP);
  232.       S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
  233.  
  234.       /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */
  235.       if (!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP))
  236.     S_SET_EXTERNAL (symbolP);
  237.  
  238.       obj_symbol_to_chars (where, symbolP);
  239.       S_SET_NAME (symbolP, temp);
  240.     }
  241. }
  242.  
  243. #endif /* ! BFD_ASSEMBLER */
  244.  
  245. static void
  246. obj_aout_line ()
  247. {
  248.   /* Assume delimiter is part of expression.
  249.      BSD4.2 as fails with delightful bug, so we
  250.      are not being incompatible here. */
  251.   new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
  252.   demand_empty_rest_of_line ();
  253. }                /* obj_aout_line() */
  254.  
  255. /*
  256.  *            stab()
  257.  *
  258.  * Handle .stabX directives, which used to be open-coded.
  259.  * So much creeping featurism overloaded the semantics that we decided
  260.  * to put all .stabX thinking in one place. Here.
  261.  *
  262.  * We try to make any .stabX directive legal. Other people's AS will often
  263.  * do assembly-time consistency checks: eg assigning meaning to n_type bits
  264.  * and "protecting" you from setting them to certain values. (They also zero
  265.  * certain bits before emitting symbols. Tut tut.)
  266.  *
  267.  * If an expression is not absolute we either gripe or use the relocation
  268.  * information. Other people's assemblers silently forget information they
  269.  * don't need and invent information they need that you didn't supply.
  270.  *
  271.  * .stabX directives always make a symbol table entry. It may be junk if
  272.  * the rest of your .stabX directive is malformed.
  273.  */
  274. static void
  275. obj_aout_stab (what)
  276.      int what;
  277. {
  278.   extern int listing;
  279.  
  280.   register symbolS *symbolP = 0;
  281.   register char *string;
  282.   int saved_type = 0;
  283.   int length;
  284.   int goof;            /* TRUE if we have aborted. */
  285.   long longint;
  286.  
  287.   /*
  288.    * Enter with input_line_pointer pointing past .stabX and any following
  289.    * whitespace.
  290.    */
  291.   goof = 0;            /* JF who forgot this?? */
  292.   if (what == 's')
  293.     {
  294.       string = demand_copy_C_string (&length);
  295.       SKIP_WHITESPACE ();
  296.       if (*input_line_pointer == ',')
  297.     input_line_pointer++;
  298.       else
  299.     {
  300.       as_bad ("I need a comma after symbol's name");
  301.       goof = 1;
  302.     }
  303.     }
  304.   else
  305.     string = "";
  306.  
  307.   /*
  308.    * Input_line_pointer->after ','.  String->symbol name.
  309.    */
  310.   if (!goof)
  311.     {
  312.       symbolP = symbol_new (string, undefined_section, 0, (struct frag *) 0);
  313.       switch (what)
  314.     {
  315.     case 'd':
  316.       S_SET_NAME (symbolP, NULL);    /* .stabd feature. */
  317.       S_SET_VALUE (symbolP, obstack_next_free (&frags) - frag_now->fr_literal);
  318.       symbolP->sy_frag = frag_now;
  319.       break;
  320.  
  321.     case 'n':
  322.       symbolP->sy_frag = &zero_address_frag;
  323.       break;
  324.  
  325.     case 's':
  326.       symbolP->sy_frag = &zero_address_frag;
  327.       break;
  328.  
  329.     default:
  330.       BAD_CASE (what);
  331.       break;
  332.     }
  333.  
  334.       if (get_absolute_expression_and_terminator (&longint) == ',')
  335.     {
  336.       saved_type = longint;
  337.       S_SET_TYPE (symbolP, saved_type);
  338.     }
  339.       else
  340.     {
  341.       as_bad ("I want a comma after the n_type expression");
  342.       goof = 1;
  343.       input_line_pointer--;    /* Backup over a non-',' char. */
  344.     }
  345.     }
  346.  
  347.   if (!goof)
  348.     {
  349.       if (get_absolute_expression_and_terminator (&longint) == ',')
  350.     S_SET_OTHER (symbolP, longint);
  351.       else
  352.     {
  353.       as_bad ("I want a comma after the n_other expression");
  354.       goof = 1;
  355.       input_line_pointer--;    /* Backup over a non-',' char. */
  356.     }
  357.     }
  358.  
  359.   if (!goof)
  360.     {
  361.       S_SET_DESC (symbolP, get_absolute_expression ());
  362.       if (what == 's' || what == 'n')
  363.     {
  364.       if (*input_line_pointer != ',')
  365.         {
  366.           as_bad ("I want a comma after the n_desc expression");
  367.           goof = 1;
  368.         }
  369.       else
  370.         {
  371.           input_line_pointer++;
  372.         }
  373.     }
  374.     }
  375.  
  376.   if ((!goof) && (what == 's' || what == 'n'))
  377.     {
  378.       pseudo_set (symbolP);
  379.       S_SET_TYPE (symbolP, saved_type);
  380.     }
  381. #ifndef NO_LISTING
  382.   if (listing && !goof)
  383.     {
  384.       if (S_GET_TYPE (symbolP) == N_SLINE)
  385.     {
  386.       listing_source_line (S_GET_DESC (symbolP));
  387.     }
  388.       else if (S_GET_TYPE (symbolP) == N_SO || S_GET_TYPE (symbolP) == N_SOL)
  389.     {
  390.       listing_source_file (string);
  391.     }
  392.     }
  393. #endif
  394.  
  395.   if (goof)
  396.     ignore_rest_of_line ();
  397.   else
  398.     demand_empty_rest_of_line ();
  399. }                /* obj_aout_stab() */
  400.  
  401. static void
  402. obj_aout_desc ()
  403. {
  404.   register char *name;
  405.   register char c;
  406.   register char *p;
  407.   register symbolS *symbolP;
  408.   register int temp;
  409.  
  410.   /*
  411.      * Frob invented at RMS' request. Set the n_desc of a symbol.
  412.  */
  413.   name = input_line_pointer;
  414.   c = get_symbol_end ();
  415.   p = input_line_pointer;
  416.   *p = c;
  417.   SKIP_WHITESPACE ();
  418.   if (*input_line_pointer != ',')
  419.     {
  420.       *p = 0;
  421.       as_bad ("Expected comma after name \"%s\"", name);
  422.       *p = c;
  423.       ignore_rest_of_line ();
  424.     }
  425.   else
  426.     {
  427.       input_line_pointer++;
  428.       temp = get_absolute_expression ();
  429.       *p = 0;
  430.       symbolP = symbol_find_or_make (name);
  431.       *p = c;
  432.       S_SET_DESC (symbolP, temp);
  433.     }
  434.   demand_empty_rest_of_line ();
  435. }                /* obj_aout_desc() */
  436.  
  437. void
  438. obj_read_begin_hook ()
  439. {
  440.   return;
  441. }                /* obj_read_begin_hook() */
  442.  
  443. #ifndef BFD_ASSEMBLER
  444.  
  445. void
  446. obj_crawl_symbol_chain (headers)
  447.      object_headers *headers;
  448. {
  449.   symbolS *symbolP;
  450.   symbolS **symbolPP;
  451.   int symbol_number = 0;
  452.  
  453.   /* JF deal with forward references first... */
  454.   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  455.     {
  456.       if (symbolP->sy_forward)
  457.     {
  458.       S_SET_VALUE (symbolP, S_GET_VALUE (symbolP)
  459.                + S_GET_VALUE (symbolP->sy_forward)
  460.                + symbolP->sy_forward->sy_frag->fr_address);
  461.  
  462.       symbolP->sy_forward = 0;
  463.     }            /* if it has a forward reference */
  464.     }                /* walk the symbol chain */
  465.  
  466.   tc_crawl_symbol_chain (headers);
  467.  
  468.   symbolPP = &symbol_rootP;    /*->last symbol chain link. */
  469.   while ((symbolP = *symbolPP) != NULL)
  470.     {
  471.       if (flagseen['R'] && (S_GET_SEGMENT (symbolP) == SEG_DATA))
  472.     {
  473.       S_SET_SEGMENT (symbolP, SEG_TEXT);
  474.     }            /* if pusing data into text */
  475.  
  476.       S_SET_VALUE (symbolP, S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
  477.  
  478.       /* OK, here is how we decide which symbols go out into the
  479.            brave new symtab.  Symbols that do are:
  480.  
  481.            * symbols with no name (stabd's?)
  482.            * symbols with debug info in their N_TYPE
  483.  
  484.            Symbols that don't are:
  485.            * symbols that are registers
  486.            * symbols with \1 as their 3rd character (numeric labels)
  487.            * "local labels" as defined by S_LOCAL_NAME(name)
  488.            if the -L switch was passed to gas.
  489.  
  490.            All other symbols are output.  We complain if a deleted
  491.            symbol was marked external. */
  492.  
  493.  
  494.       if (!S_IS_REGISTER (symbolP)
  495.       && (!S_GET_NAME (symbolP)
  496.           || S_IS_DEBUG (symbolP)
  497. #ifdef TC_I960
  498.       /* FIXME-SOON this ifdef seems highly dubious to me.  xoxorich. */
  499.           || !S_IS_DEFINED (symbolP)
  500.           || S_IS_EXTERNAL (symbolP)
  501. #endif /* TC_I960 */
  502.           || (S_GET_NAME (symbolP)[0] != '\001' && (flagseen['L'] || !S_LOCAL_NAME (symbolP)))))
  503.     {
  504.       symbolP->sy_number = symbol_number++;
  505.  
  506.       /* The + 1 after strlen account for the \0 at the
  507.                end of each string */
  508.       if (!S_IS_STABD (symbolP))
  509.         {
  510.           /* Ordinary case. */
  511.           symbolP->sy_name_offset = string_byte_count;
  512.           string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
  513.         }
  514.       else            /* .Stabd case. */
  515.         symbolP->sy_name_offset = 0;
  516.       symbolPP = &(symbol_next (symbolP));
  517.     }
  518.       else
  519.     {
  520.       if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
  521.         {
  522.           as_bad ("Local symbol %s never defined.", decode_local_label_name (S_GET_NAME (symbolP)));
  523.         }            /* oops. */
  524.  
  525.       /* Unhook it from the chain */
  526.       *symbolPP = symbol_next (symbolP);
  527.     }            /* if this symbol should be in the output */
  528.     }                /* for each symbol */
  529.  
  530.   H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
  531.  
  532.   return;
  533. }                /* obj_crawl_symbol_chain() */
  534.  
  535. /*
  536.  * Find strings by crawling along symbol table chain.
  537.  */
  538.  
  539. void
  540. obj_emit_strings (where)
  541.      char **where;
  542. {
  543.   symbolS *symbolP;
  544.  
  545. #ifdef CROSS_COMPILE
  546.   /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
  547.   md_number_to_chars (*where, string_byte_count, sizeof (string_byte_count));
  548.   *where += sizeof (string_byte_count);
  549. #else /* CROSS_COMPILE */
  550.   append (where, (char *) &string_byte_count, (unsigned long) sizeof (string_byte_count));
  551. #endif /* CROSS_COMPILE */
  552.  
  553.   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  554.     {
  555.       if (S_GET_NAME (symbolP))
  556.     append (&next_object_file_charP, S_GET_NAME (symbolP),
  557.         (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1));
  558.     }                /* walk symbol chain */
  559.  
  560.   return;
  561. }                /* obj_emit_strings() */
  562.  
  563. #ifndef AOUT_VERSION
  564. #define AOUT_VERSION 0
  565. #endif
  566.  
  567. void
  568. obj_pre_write_hook (headers)
  569.      object_headers *headers;
  570. {
  571.   H_SET_DYNAMIC (headers, 0);
  572.   H_SET_VERSION (headers, AOUT_VERSION);
  573.   H_SET_MACHTYPE (headers, AOUT_MACHTYPE);
  574.   tc_aout_pre_write_hook (headers);
  575.   return;
  576. }                /* obj_pre_write_hook() */
  577.  
  578. void
  579. DEFUN_VOID (s_sect)
  580. {
  581.   /* Strip out the section name */
  582.   char *section_name;
  583.   char *section_name_end;
  584.   char c;
  585.  
  586.   unsigned int len;
  587.   unsigned int exp;
  588.   char *save;
  589.  
  590.   section_name = input_line_pointer;
  591.   c = get_symbol_end ();
  592.   section_name_end = input_line_pointer;
  593.  
  594.   len = section_name_end - section_name;
  595.   input_line_pointer++;
  596.   save = input_line_pointer;
  597.  
  598.   SKIP_WHITESPACE ();
  599.   if (c == ',')
  600.     {
  601.       exp = get_absolute_expression ();
  602.     }
  603.   else if (*input_line_pointer == ',')
  604.     {
  605.       input_line_pointer++;
  606.       exp = get_absolute_expression ();
  607.     }
  608.   else
  609.     {
  610.       input_line_pointer = save;
  611.       exp = 0;
  612.     }
  613.   if (exp >= 1000)
  614.     {
  615.       as_bad ("subsegment index too high");
  616.     }
  617.   if (strcmp (section_name, ".text") == 0)
  618.     {
  619.       subseg_new (SEG_TEXT, (subsegT) exp);
  620.     }
  621.  
  622.   if (strcmp (section_name, ".data") == 0)
  623.     {
  624.       subseg_new (SEG_DATA, (subsegT) exp);
  625.     }
  626.  
  627.   *section_name_end = c;
  628. }
  629.  
  630. #endif /* ! BFD_ASSEMBLER */
  631.  
  632. /* end of obj-aout.c */
  633.